package auth

import (
	"errors"
	"github.com/golang-jwt/jwt/v4"
	"strconv"
	"time"
)

const TokenExpireDuration = time.Hour * 2

var signKey = []byte("7059184806906560543") // 生成签名的密钥

type UserInfo struct {
	Id       uint64  `json:"id"`
	UserName string  `json:"user_name"`
	Email    *string `json:"email,omitempty"`
	RealName *string `json:"real_name,omitempty"`
	Phone    *string `json:"phone,omitempty"`
	Token    *string `json:"token,omitempty"`
	RoleCode string  `json:"role_code"`
}

type CustomClaims struct {
	User *UserInfo
	jwt.RegisteredClaims
}

func GenerateToken(user *UserInfo) (string, error) {
	claims := CustomClaims{
		User: user,
		RegisteredClaims: jwt.RegisteredClaims{
			// iss:定义发布者
			Issuer: "yang jun",
			// sub：该JWT所面向的用户
			Subject: "sub",
			// iat:签发时间
			IssuedAt: &jwt.NumericDate{
				Time: time.Now(),
			},
			// aud：接收该JWT的一方
			Audience: []string{},
			// exp:定义token的过期时间
			ExpiresAt: &jwt.NumericDate{
				Time: time.Now().Add(TokenExpireDuration),
			},
			// nbf:生效时间
			NotBefore: &jwt.NumericDate{
				Time: time.Now(),
			},
			// jti:编号
			ID: strconv.Itoa(int(user.Id)),
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString(signKey)
}

func ParseToken(tokenString string) (*CustomClaims, error) {
	claims := &CustomClaims{}
	token, err := jwt.ParseWithClaims(tokenString, claims, func(t *jwt.Token) (interface{}, error) {
		return signKey, nil
	})
	if err != nil {
		return claims, err
	}
	if token.Valid {
		return claims, nil
	}
	return nil, errors.New("token无法解析")
}

// 若token过期不超过5分钟则给它续签
func RenewToken(claims *CustomClaims) (string, error) {
	dev := time.Now().Unix() - claims.ExpiresAt.Unix()
	if dev < 300 {
		return GenerateToken(claims.User)
	}
	return "", errors.New("登录已过期")
}
